home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / bc_ti.zip / TI738.ASC < prev    next >
Text File  |  1992-02-25  |  38KB  |  991 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.   PRODUCT  :  Borland C++                            NUMBER  :  738
  9.   VERSION  :  All
  10.        OS  :  DOS
  11.      DATE  :  February 25, 1992                       PAGE  :  1/15
  12.  
  13.     TITLE  :  Memory Corruption
  14.  
  15.  
  16.  
  17.  
  18.   POINTERS:
  19.  
  20.   A pointer is a memory location that holds a memory address as its
  21.   contents. When you declare a pointer (e.g. int *foo) the compiler
  22.   will allocate the necessary space to hold the appropriate memory
  23.   address. If the pointer is declared globally the value of its
  24.   address will be 0000 in the case of a near pointer and 0000:0000
  25.   in the case of a far pointer. If the pointer is declared inside a
  26.   function definition as an auto variable (default), then it is
  27.   created on the stack and will have a default address of whatever
  28.   value happened to be at that location on the stack when it is
  29.   created. In either case these default memory addresses are
  30.   invalid. This is referred to as an uninitialized pointer and
  31.   should never be dereferenced. To initialize a pointer you must
  32.   either dynamically allocate memory using malloc, farmalloc,
  33.   calloc, farcalloc, realloc, farrealloc, allocmem or new (C++
  34.   only) or you can associate the pointer with a variable who's
  35.   memory is allocated by the compiler at compile time (e.g. int
  36.   foo[100]). Once the pointer has been initialized it is then safe
  37.   to dereference the pointer using the * operator.
  38.  
  39.        int *p;   OK  Uninitialized pointer
  40.        *p = 4;   WRONG This puts a value of 4 at whatever
  41.                  address happened to be stored where *p was
  42.                  created.
  43.        int  i;   OK  Statically declared variable. Static meaning
  44.                  the memory is allocated by the compiler at
  45.                  compile time.
  46.  
  47.        p = &i;   OK  Associating p with a statically declared
  48.                  variable.
  49.        p = (int *) malloc(2); OK  Associating p with dynamically
  50.                  allocated memory. The parameter could also have
  51.                  been sizeof(int).
  52.  
  53.   Modifying the variable p (e.g. p = 0;) will make the memory
  54.   address that p holds equal to 0. When modifying dereferenced p,
  55.   denoted by *p, the value stored at the memory address p holds as
  56.   its value is modified.
  57.  
  58.        *p = 4;   OK  p still holds the address that malloc
  59.                  returned above, but that address in memory
  60.                  now holds a value of 4.
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.   PRODUCT  :  Borland C++                            NUMBER  :  738
  75.   VERSION  :  All
  76.        OS  :  DOS
  77.      DATE  :  February 25, 1992                       PAGE  :  2/15
  78.  
  79.     TITLE  :  Memory Corruption
  80.  
  81.  
  82.  
  83.  
  84.        p = 4;    OK  *p now points to offset 4 from DS. It is
  85.                  important to note that this type of assignment
  86.                  should only be made if the address (4 in this
  87.                  case) is valid. Otherwise memory corruption
  88.                  will occur. Also note that if a far memory
  89.                  model (see Memory Models) is used the segment
  90.                  may not be DS, but will be whatever its initial
  91.                  value was.
  92.  
  93.   There are 3 types of pointers. They are near, far, and huge.
  94.  
  95.   Near pointers have a size of 2 bytes. They only store the offset
  96.   of the address the pointer is referencing. An address consisting
  97.   of only an offset has a range of 0 - 64K bytes starting from the
  98.   beginning of DGROUP. A near pointer can be incremented and
  99.   decremented using arithmetic operators (+, -, ++, and --) through
  100.   the entire address range. Any attempt to increment a near pointer
  101.   that has a value of 64K (0xffff) will result in a value of 0.
  102.   This is referred to as wrapping the pointer. A corresponding
  103.   result can be expected when attempting to decrement a pointer
  104.   that contains an address of 0, except the result will be 64K
  105.   instead of 0. In addition to being incremented and decremented,
  106.   near pointers can be compared to one another using relational
  107.   operators ( <, >, ==, >= and <= ).
  108.  
  109.   Far pointers have a size of 4 bytes. They store both the segment
  110.   and the offset of the address the pointer is referencing. A far
  111.   pointer has an address range of 0 - 1M bytes. It is important to
  112.   understand that an addressing range of 1M does not remove the
  113.   640K barrier from the program. It means that the pointer can
  114.   address the upper memory area (641 - 1M) which typically contains
  115.   video memory, ROM and anything else that may be loaded high. A
  116.   far pointer can be incremented and decremented using arithmetic
  117.   operators. When a far pointer is incremented or decremented ONLY
  118.   the offset of the pointer is actually incremented or decremented.
  119.   The segment is never incremented by the arithmetic operators.
  120.   This means that although a far pointer can address up to 1Mb of
  121.   memory, it can only be incremented through 64Kb and the offset
  122.   will start at zero again without changing the value of the
  123.   segment. This is referred to as "wrapping" the pointer (e.g.
  124.   0F3E:FFFF + 1 = 0F3E:0000). When a far pointer is decremented
  125.   from zero it will wrap the other way and become 64K. Far pointers
  126.   are not unique. It is possible to have two far memory addresses
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.   PRODUCT  :  Borland C++                            NUMBER  :  738
  141.   VERSION  :  All
  142.        OS  :  DOS
  143.      DATE  :  February 25, 1992                       PAGE  :  3/15
  144.  
  145.     TITLE  :  Memory Corruption
  146.  
  147.  
  148.  
  149.  
  150.   that have different segment values and different offset values
  151.   that address the same memory location e.g. 0777:2222 has an
  152.   absolute address of 07770 + 2222 = 09992 and 0999:0002 has an
  153.   absolute address of 09990 + 0002 = 09992. When relational
  154.   operators are used on far pointers only the offsets are compared.
  155.   For example: if we let a = 0777:2222 and let b = 0999:0002 then a
  156.   == b would return false because this is equivalent to 2222 ==
  157.   0002 which is in fact false. In other words relational operators
  158.   will only work on far pointers if the segment values of the
  159.   pointers being compared are the same.
  160.  
  161.   Huge pointers have a size of 4 bytes. They store both the segment
  162.   and the offset of the address the pointer is referencing. A huge
  163.   pointer has an address range of 0 - 1M bytes. A huge pointer can
  164.   be incremented and decremented using arithmetic operators. The
  165.   only difference between a far pointer and a huge pointer is that
  166.   a huge pointer is normalized by the compiler. A normalized
  167.   pointer is one that has as much of the address as possible in the
  168.   segment, meaning that the offset is never larger than 15. A huge
  169.   pointer is normalized only when pointer arithmetic is performed
  170.   on it. It is not normalized when an assignment is made. You can
  171.   cause it to be normalized without changing the value by
  172.   incrementing and then decrementing it. The offset must be less
  173.   than 16 because the segment can represent any value greater than
  174.   or equal to 16 (e.g. Absolute address 0x17 in a normalized form
  175.   would be 0001:0001. While a far pointer could address the
  176.   absolute address 0x17 with 0000:0017, this is not a valid huge
  177.   (normalized) pointer because the offset is greater than 0000F.).
  178.   Huge pointers can also be incremented and decremented using
  179.   arithmetic operators, but since they are normalized they will not
  180.   wrap like far pointers. Huge pointers can be reliably used with
  181.   relational operators because they are normalized. This works
  182.   because normalization of huge pointers insures that every huge
  183.   pointer is unique. It is important to understand that huge
  184.   pointers are never the default pointer, even in the huge memory
  185.   model.
  186.  
  187.   MEMORY MODELS:
  188.  
  189.   The important difference between the memory models are the size
  190.   of the data and code pointers, number of data and code segments
  191.   and the number and type of heaps available. For our purposes we
  192.   will refer to the tiny, small and medium memory models as near
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.   PRODUCT  :  Borland C++                            NUMBER  :  738
  207.   VERSION  :  All
  208.        OS  :  DOS
  209.      DATE  :  February 25, 1992